<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  
  
  
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <title>
    浅谈Kotlin反射 |
    
    OOOOONLY</title>
  
    <link rel="shortcut icon" href="/favicon.ico">
  
  
<link rel="stylesheet" href="/css/style.css">

  
    
<link rel="stylesheet" href="/fancybox/jquery.fancybox.min.css">

  
  
<script src="/js/pace.min.js"></script>

<meta name="generator" content="Hexo 4.2.0"></head>

<body>
<main class="content">
  <section class="outer">
  <article id="post-浅谈Kotlin反射" class="article article-type-post" itemscope itemprop="blogPost" data-scroll-reveal>

    <div class="article-inner">
        
            <header class="article-header">
                
  
    <h1 class="article-title" itemprop="name">
      浅谈Kotlin反射
    </h1>
  
  




            </header>
            

                
                    <div class="article-meta">
                        <a href="/2020/07/08/%E6%B5%85%E8%B0%88Kotlin%E5%8F%8D%E5%B0%84/" class="article-date">
  <time datetime="2020-07-08T02:50:15.000Z" itemprop="datePublished">2020-07-08</time>
</a>
                            
                    </div>
                    

                        
                            
    <div class="tocbot"></div>





                                

                                    <div class="article-entry" itemprop="articleBody">
                                        


                                            

                                                
                                                                    <h1 id="浅谈Kotlin反射"><a href="#浅谈Kotlin反射" class="headerlink" title="浅谈Kotlin反射"></a>浅谈Kotlin反射</h1><blockquote>
<p>反射是这样的一组语言和库功能，它允许在运行时自省你的程序的结构。 Kotlin 让语言中的函数和属性做为一等公民、并对其自省（即在运行时获悉一个名称或者一个属性或函数的类型）与简单地使用函数式或响应式风格紧密相关。</p>
</blockquote>
<a id="more"></a>

<h2 id="类引用"><a href="#类引用" class="headerlink" title="类引用"></a>类引用</h2><p>最基本的反射功能是获取 Kotlin 类的运行时引用。要获取对静态已知的 Kotlin 类的引用，可以使用 <em>类字面值</em> 语法：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> c = MyClass::<span class="class"><span class="keyword">class</span></span></span><br></pre></td></tr></table></figure>

<p>该引用是 KClass类型的值。</p>
<p>请注意，Kotlin 类引用与 Java 类引用不同。要获得 Java 类引用， 请在 <code>KClass</code> 实例上使用 <code>.java</code> 属性。</p>
<h2 id="绑定的类引用（自-1-1-起）"><a href="#绑定的类引用（自-1-1-起）" class="headerlink" title="绑定的类引用（自 1.1 起）"></a>绑定的类引用（自 1.1 起）</h2><p>通过使用对象作为接收者，可以用相同的 <code>::class</code> 语法获取指定对象的类的引用：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> widget: Widget = ……</span><br><span class="line">assert(widget <span class="keyword">is</span> GoodWidget) &#123; <span class="string">"Bad widget: <span class="subst">$&#123;widget::class.qualifiedName&#125;</span>"</span> &#125;</span><br></pre></td></tr></table></figure>

<p>你可以获取对象的精确类的引用，例如 <code>GoodWidget</code> 或 <code>BadWidget</code>，尽管接收者表达式的类型是 <code>Widget</code>。</p>
<h2 id="可调用引用"><a href="#可调用引用" class="headerlink" title="可调用引用"></a>可调用引用</h2><p>函数、属性以及构造函数的引用，除了作为自省程序结构外， 还可以用于调用或者用作函数类型的实例。</p>
<p>所有可调用引用的公共超类型是 KCallable， 其中 <code>R</code> 是返回值类型，对于属性是属性类型，对于构造函数是所构造类型。</p>
<h3 id="函数引用"><a href="#函数引用" class="headerlink" title="函数引用"></a>函数引用</h3><p>当我们有一个具名函数声明如下：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">isOdd</span><span class="params">(x: <span class="type">Int</span>)</span></span> = x % <span class="number">2</span> != <span class="number">0</span></span><br></pre></td></tr></table></figure>

<p>我们可以很容易地直接调用它（<code>isOdd(5)</code>），但是我们也可以将其作为一个函数类型的值，例如将其传给另一个函数。为此，我们使用 <code>::</code> 操作符：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> numbers = listOf(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)</span><br><span class="line">println(numbers.filter(::isOdd))</span><br></pre></td></tr></table></figure>

<p>Target platform: JVMRunning on kotlin v. 1.3.72</p>
<p>这里 <code>::isOdd</code> 是函数类型 <code>(Int) -&gt; Boolean</code> 的一个值。</p>
<p>函数引用属于 KFunction的子类型之一，取决于参数个数，例如 <code>KFunction3</code>。</p>
<p>当上下文中已知函数期望的类型时，<code>::</code> 可以用于重载函数。 例如：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">isOdd</span><span class="params">(x: <span class="type">Int</span>)</span></span> = x % <span class="number">2</span> != <span class="number">0</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">isOdd</span><span class="params">(s: <span class="type">String</span>)</span></span> = s == <span class="string">"brillig"</span> || s == <span class="string">"slithy"</span> || s == <span class="string">"tove"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">val</span> numbers = listOf(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)</span><br><span class="line">println(numbers.filter(::isOdd)) <span class="comment">// 引用到 isOdd(x: Int)</span></span><br></pre></td></tr></table></figure>

<p>Target platform: JVMRunning on kotlin v. 1.3.72</p>
<p>或者，你可以通过将方法引用存储在具有显式指定类型的变量中来提供必要的上下文：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> predicate: (String) -&gt; <span class="built_in">Boolean</span> = ::isOdd   <span class="comment">// 引用到 isOdd(x: String)</span></span><br></pre></td></tr></table></figure>

<p>如果我们需要使用类的成员函数或扩展函数，它需要是限定的，例如 <code>String::toCharArray</code>。</p>
<p>请注意，即使以扩展函数的引用初始化一个变量，其推断出的函数类型也会没有接收者（它会有一个接受接收者对象的额外参数）。如需改为带有接收者的函数类型，请明确指定其类型：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> isEmptyStringList: List&lt;String&gt;.() -&gt; <span class="built_in">Boolean</span> = List&lt;String&gt;::isEmpty</span><br></pre></td></tr></table></figure>

<h3 id="示例：函数组合"><a href="#示例：函数组合" class="headerlink" title="示例：函数组合"></a>示例：函数组合</h3><p>考虑以下函数：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fun</span> <span class="type">&lt;A, B, C&gt;</span> <span class="title">compose</span><span class="params">(f: (<span class="type">B</span>) -&gt; <span class="type">C</span>, g: (<span class="type">A</span>) -&gt; <span class="type">B</span>)</span></span>: (A) -&gt; C &#123;</span><br><span class="line">    <span class="keyword">return</span> &#123; x -&gt; f(g(x)) &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>它返回一个传给它的两个函数的组合：<code>compose(f, g) = f(g(*))</code>。 现在，你可以将其应用于可调用引用：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">length</span><span class="params">(s: <span class="type">String</span>)</span></span> = s.length</span><br><span class="line"></span><br><span class="line"><span class="keyword">val</span> oddLength = compose(::isOdd, ::length)</span><br><span class="line"><span class="keyword">val</span> strings = listOf(<span class="string">"a"</span>, <span class="string">"ab"</span>, <span class="string">"abc"</span>)</span><br><span class="line"></span><br><span class="line">println(strings.filter(oddLength))</span><br></pre></td></tr></table></figure>



<h3 id="属性引用"><a href="#属性引用" class="headerlink" title="属性引用"></a>属性引用</h3><p>要把属性作为 Kotlin中 的一等对象来访问，我们也可以使用 <code>::</code> 运算符：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> x = <span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    println(::x.<span class="keyword">get</span>())</span><br><span class="line">    println(::x.name) </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Target platform: JVMRunning on kotlin v. 1.3.72</p>
<p>表达式 <code>::x</code> 求值为 <code>KProperty</code> 类型的属性对象，它允许我们使用 <code>get()</code> 读取它的值，或者使用 <code>name</code> 属性来获取属性名。</p>
<p>对于可变属性，例如 <code>var y = 1</code>，<code>::y</code> 返回 KMutableProperty类型的一个值， 该类型有一个 <code>set()</code> 方法。</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> y = <span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    ::y.<span class="keyword">set</span>(<span class="number">2</span>)</span><br><span class="line">    println(y)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Target platform: JVMRunning on kotlin v. 1.3.72</p>
<p>属性引用可以用在预期具有单个泛型参数的函数的地方：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> strs = listOf(<span class="string">"a"</span>, <span class="string">"bc"</span>, <span class="string">"def"</span>)</span><br><span class="line">println(strs.map(String::length))</span><br></pre></td></tr></table></figure>

<p>Target platform: JVMRunning on kotlin v. 1.3.72</p>
<p>要访问属于类的成员的属性，我们这样限定它：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span></span>(<span class="keyword">val</span> p: <span class="built_in">Int</span>)</span><br><span class="line"><span class="keyword">val</span> prop = A::p</span><br><span class="line">println(prop.<span class="keyword">get</span>(A(<span class="number">1</span>)))</span><br></pre></td></tr></table></figure>

<p>Target platform: JVMRunning on kotlin v. 1.3.72</p>
<p>对于扩展属性：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> String.lastChar: <span class="built_in">Char</span></span><br><span class="line">    <span class="keyword">get</span>() = <span class="keyword">this</span>[length - <span class="number">1</span>]</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    println(String::lastChar.<span class="keyword">get</span>(<span class="string">"abc"</span>))</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Target platform: JVMRunning on kotlin v. 1.3.72</p>
<h3 id="与-Java-反射的互操作性"><a href="#与-Java-反射的互操作性" class="headerlink" title="与 Java 反射的互操作性"></a>与 Java 反射的互操作性</h3><p>在Java平台上，标准库包含反射类的扩展，它提供了与 Java 反射对象之间映射（参见 <code>kotlin.reflect.jvm</code> 包）。 例如，要查找一个用作 Kotlin 属性 getter 的 幕后字段或 Java方法，可以这样写：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> kotlin.reflect.jvm.*</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span></span>(<span class="keyword">val</span> p: <span class="built_in">Int</span>)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    println(A::p.javaGetter) <span class="comment">// 输出 "public final int A.getP()"</span></span><br><span class="line">    println(A::p.javaField)  <span class="comment">// 输出 "private final int A.p"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>要获得对应于 Java 类的 Kotlin 类，请使用 <code>.kotlin</code> 扩展属性：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">getKClass</span><span class="params">(o: <span class="type">Any</span>)</span></span>: KClass&lt;Any&gt; = o.javaClass.kotlin</span><br></pre></td></tr></table></figure>

<h3 id="构造函数引用"><a href="#构造函数引用" class="headerlink" title="构造函数引用"></a>构造函数引用</h3><p>构造函数可以像方法和属性那样引用。他们可以用于期待这样的函数类型对象的任何地方：它与该构造函数接受相同参数并且返回相应类型的对象。 通过使用 <code>::</code> 操作符并添加类名来引用构造函数。考虑下面的函数， 它期待一个无参并返回 <code>Foo</code> 类型的函数参数：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">function</span><span class="params">(factory: () -&gt; <span class="type">Foo</span>)</span></span> &#123;</span><br><span class="line">    <span class="keyword">val</span> x: Foo = factory()</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>使用 <code>::Foo</code>，类 Foo 的零参数构造函数，我们可以这样简单地调用它：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">function(::Foo)</span><br></pre></td></tr></table></figure>

<p>构造函数的可调用引用的类型也是KFunction的子类型之一 ，取决于其参数个数。</p>
<h2 id="绑定的函数与属性引用（自-1-1-起）"><a href="#绑定的函数与属性引用（自-1-1-起）" class="headerlink" title="绑定的函数与属性引用（自 1.1 起）"></a>绑定的函数与属性引用（自 1.1 起）</h2><p>你可以引用特定对象的实例方法：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> numberRegex = <span class="string">"\\d+"</span>.toRegex()</span><br><span class="line">println(numberRegex.matches(<span class="string">"29"</span>))</span><br><span class="line"></span><br><span class="line"><span class="keyword">val</span> isNumber = numberRegex::matches</span><br><span class="line">println(isNumber(<span class="string">"29"</span>))</span><br></pre></td></tr></table></figure>

<p>Target platform: JVMRunning on kotlin v. 1.3.72</p>
<p>取代直接调用方法 <code>matches</code> 的是我们存储其引用。 这样的引用会绑定到其接收者上。 它可以直接调用（如上例所示）或者用于任何期待一个函数类型表达式的时候：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> numberRegex = <span class="string">"\\d+"</span>.toRegex()</span><br><span class="line"><span class="keyword">val</span> strings = listOf(<span class="string">"abc"</span>, <span class="string">"124"</span>, <span class="string">"a70"</span>)</span><br><span class="line">println(strings.filter(numberRegex::matches))</span><br></pre></td></tr></table></figure>

<p>Target platform: JVMRunning on kotlin v. 1.3.72</p>
<p>比较绑定的类型和相应的未绑定类型的引用。 绑定的可调用引用有其接收者“附加”到其上，因此接收者的类型不再是参数：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> isNumber: (CharSequence) -&gt; <span class="built_in">Boolean</span> = numberRegex::matches</span><br><span class="line"></span><br><span class="line"><span class="keyword">val</span> matches: (Regex, CharSequence) -&gt; <span class="built_in">Boolean</span> = Regex::matches</span><br></pre></td></tr></table></figure>

<p>属性引用也可以绑定：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> prop = <span class="string">"abc"</span>::length</span><br><span class="line">println(prop.<span class="keyword">get</span>())</span><br></pre></td></tr></table></figure>

<p>Target platform: JVMRunning on kotlin v. 1.3.72</p>
<p>自 Kotlin 1.2 起，无需显式指定 <code>this</code> 作为接收者：<code>this::foo</code> 与 <code>::foo</code> 是等价的。</p>
<h3 id="绑定的构造函数引用"><a href="#绑定的构造函数引用" class="headerlink" title="绑定的构造函数引用"></a>绑定的构造函数引用</h3><p><em>inner</em> 类的构造函数的绑定的可调用引用可通过提供外部类的实例来获得：</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Outer</span> </span>&#123;</span><br><span class="line">    <span class="keyword">inner</span> <span class="class"><span class="keyword">class</span> <span class="title">Inner</span></span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">val</span> o = Outer()</span><br><span class="line"><span class="keyword">val</span> boundInnerCtor = o::Inner</span><br></pre></td></tr></table></figure>



<h2 id="类方法参考"><a href="#类方法参考" class="headerlink" title="类方法参考"></a>类方法参考</h2><p>在Kotlin中，字节码对应的类是kotlin.reflect.KClass，因为Kotlin百分之百兼容Java，所以Kotlin中可以使用Java中的反射，但是由于Kotlin中字节码.class对应的是KClass类，所以如果想要使用Java中的反射，需要首先获取Class的实例，在Kotlin中可以通过以下两种方式来获取Class实例。</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//1.通过实例.javaClass</span></span><br><span class="line"><span class="keyword">var</span> hello = HelloWorld()</span><br><span class="line">hello.javaClass</span><br><span class="line"></span><br><span class="line"> <span class="comment">//2.通过类Kclass类的.java属性</span></span><br><span class="line">HelloWorld::<span class="class"><span class="keyword">class</span>.<span class="title">java</span></span></span><br></pre></td></tr></table></figure>

<p>获取了Class实例，就可以调用上面介绍的方法，获取各种在Java中定义的类的信息了。</p>
<p>当然Kotlin中除了可以使用Java中的反射以外，还可以使用Kotlin中声明的一些方法，当然同Java中反射一样，想要使用这些方法，先要获取Kclass对象，在Kotlin中可以通过以下两种方式获取Kclass实例。</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment">//1.通过类::class的方式获取Kclass实例</span></span><br><span class="line"><span class="keyword">val</span> clazz1: KClass&lt;*&gt; = HelloWorld::<span class="class"><span class="keyword">class</span></span></span><br><span class="line"><span class="comment">//2.通过实例.javaClass.kotlin获取Kclass实例</span></span><br><span class="line"><span class="keyword">var</span> hello = HelloWorld()</span><br><span class="line"><span class="keyword">val</span> clazz2 = hello.javaClass.kotlin</span><br></pre></td></tr></table></figure>

<p>获取了Kclass实例之后，就可以调用Kotlin中声明的一些关于反射的方法了，那么都有哪些方法呢？</p>
<h3 id="构造函数Constructor"><a href="#构造函数Constructor" class="headerlink" title="构造函数Constructor"></a>构造函数Constructor</h3><p>Kotlin可以通过下面的方法，获取所有的构造函数。</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//返回这个类的所有构造器</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> constructors: Collection&lt;KFunction&lt;T&gt;&gt;</span><br></pre></td></tr></table></figure>



<h3 id="成员变量和成员函数"><a href="#成员变量和成员函数" class="headerlink" title="成员变量和成员函数"></a>成员变量和成员函数</h3><p>Kotlin中获取成员变量和成员函数的方法有6个。</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//返回类可访问的所有函数和属性，包括继承自基类的，但是不包括构造器</span></span><br><span class="line"><span class="keyword">override</span> <span class="keyword">val</span> members: Collection&lt;KCallable&lt;*&gt;&gt;</span><br><span class="line"><span class="comment">//返回类声明的所有函数</span></span><br><span class="line"><span class="keyword">val</span> KClass&lt;*&gt;.declaredFunctions: Collection&lt;KFunction&lt;*&gt;&gt;</span><br><span class="line"><span class="comment">//返回类的扩展函数</span></span><br><span class="line"><span class="keyword">val</span> KClass&lt;*&gt;.declaredMemberExtensionFunctions: Collection&lt;KFunction&lt;*&gt;&gt;</span><br><span class="line"><span class="comment">//返回类的扩展属性</span></span><br><span class="line"><span class="keyword">val</span> &lt;T : Any&gt; KClass&lt;T&gt;.declaredMemberExtensionProperties: Collection&lt;KProperty2&lt;T, *, *&gt;&gt;</span><br><span class="line"><span class="comment">//返回类自身声明的成员函数</span></span><br><span class="line"><span class="keyword">val</span> KClass&lt;*&gt;.declaredMemberFunctions: Collection&lt;KFunction&lt;*&gt;&gt;</span><br><span class="line"><span class="comment">//返回类自身声明的成员变量（属性）</span></span><br><span class="line"><span class="keyword">val</span> &lt;T : Any&gt; KClass&lt;T&gt;.declaredMemberProperties: Collection&lt;KProperty1&lt;T, *&gt;&gt;</span><br></pre></td></tr></table></figure>



<h3 id="类相关信息"><a href="#类相关信息" class="headerlink" title="类相关信息"></a>类相关信息</h3><p>可以看到Kotlin反射中，可以获取比Java反射更多的关于类的信息。</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//1.返回类的名字</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> simpleName: String?</span><br><span class="line"> <span class="comment">//2.返回类的全包名</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> qualifiedName: String?</span><br><span class="line"><span class="comment">//3.如果这个类声明为object，则返回其实例，否则返回null</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> objectInstance: T?</span><br><span class="line"><span class="comment">//4.返回类的可见性</span></span><br><span class="line"><span class="meta">@SinceKotlin(<span class="meta-string">"1.1"</span>)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> visibility: KVisibility?</span><br><span class="line"><span class="comment">//5.判断类是否为final类（在Kotlin中，类默认是final的，除非这个类声明为open或者abstract)</span></span><br><span class="line"><span class="meta">@SinceKotlin(<span class="meta-string">"1.1"</span>)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> isFinal: <span class="built_in">Boolean</span></span><br><span class="line"><span class="comment">//6.判断类是否是open的(abstract类也是open的），表示这个类可以被继承</span></span><br><span class="line"><span class="meta">@SinceKotlin(<span class="meta-string">"1.1"</span>)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> isOpen: <span class="built_in">Boolean</span></span><br><span class="line"><span class="comment">//7.判断类是否为抽象类</span></span><br><span class="line"><span class="meta">@SinceKotlin(<span class="meta-string">"1.1"</span>)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> isAbstract: <span class="built_in">Boolean</span></span><br><span class="line"><span class="comment">//8.判断类是否为密封类，密封类:用sealed修饰，其子类只能在其内部定义</span></span><br><span class="line"><span class="meta">@SinceKotlin(<span class="meta-string">"1.1"</span>)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> isSealed: <span class="built_in">Boolean</span></span><br><span class="line"><span class="comment">//9.判断类是否为data类</span></span><br><span class="line"><span class="meta">@SinceKotlin(<span class="meta-string">"1.1"</span>)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> isData: <span class="built_in">Boolean</span></span><br><span class="line"><span class="comment">//10.判断类是否为成员类</span></span><br><span class="line"><span class="meta">@SinceKotlin(<span class="meta-string">"1.1"</span>)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> isInner: <span class="built_in">Boolean</span></span><br><span class="line"><span class="comment">//11.判断类是否为companion object</span></span><br><span class="line"><span class="meta">@SinceKotlin(<span class="meta-string">"1.1"</span>)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> isCompanion: <span class="built_in">Boolean</span>    </span><br><span class="line"><span class="comment">//12.返回类中定义的其他类，包括内部类(inner class声明的)和嵌套类(class声明的)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> nestedClasses: Collection&lt;KClass&lt;*&gt;&gt;</span><br><span class="line"> <span class="comment">//13.判断一个对象是否为此类的实例</span></span><br><span class="line"><span class="meta">@SinceKotlin(<span class="meta-string">"1.1"</span>)</span></span><br><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">fun</span> <span class="title">isInstance</span><span class="params">(value: <span class="type">Any</span>?)</span></span>: <span class="built_in">Boolean</span></span><br><span class="line"><span class="comment">//14.返回这个类的泛型列表</span></span><br><span class="line"><span class="meta">@SinceKotlin(<span class="meta-string">"1.1"</span>)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> typeParameters: List&lt;KTypeParameter&gt;</span><br><span class="line"><span class="comment">//15.类其直接基类的列表</span></span><br><span class="line"><span class="meta">@SinceKotlin(<span class="meta-string">"1.1"</span>)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">val</span> supertypes: List&lt;KType&gt;</span><br><span class="line"><span class="comment">//16.返回类所有的基类</span></span><br><span class="line"><span class="keyword">val</span> KClass&lt;*&gt;.allSuperclasses: Collection&lt;KClass&lt;*&gt;&gt;</span><br><span class="line"><span class="comment">//17.返回类的伴生对象companionObject</span></span><br><span class="line"><span class="keyword">val</span> KClass&lt;*&gt;.companionObject: KClass&lt;*&gt;?</span><br></pre></td></tr></table></figure>
                                                                        
                                    </div>
                                    <footer class="article-footer">
                                        <a data-url="http://only52607.github.io/2020/07/08/%E6%B5%85%E8%B0%88Kotlin%E5%8F%8D%E5%B0%84/" data-id="ckcctc2ro0001y8u10bas3lex" class="article-share-link">
                                            Share
                                        </a>
                                        
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Kotlin/" rel="tag">Kotlin</a></li></ul>

                                    </footer>

    </div>

    
        
  <nav class="article-nav">
    
      <a href="/2020/07/08/Lua%E5%AD%97%E8%8A%82%E7%A0%81%E5%89%96%E6%9E%90-%E5%9F%BA%E4%BA%8ELua5-2/" class="article-nav-link">
        <strong class="article-nav-caption">Newer</strong>
        <div class="article-nav-title">
          
            Lua字节码剖析(基于Lua5.2)
          
        </div>
      </a>
    
    
      <a href="/2020/07/06/Markdown-%E8%AF%AD%E6%B3%95%E9%80%9F%E6%9F%A5/" class="article-nav-link">
        <strong class="article-nav-caption">Older</strong>
        <div class="article-nav-title">Markdown 语法速查</div>
      </a>
    
  </nav>


            

                
                    
                        
                            

</article>
</section>
  <footer class="footer">
  <div class="outer">
    <div class="float-right">
      <ul class="list-inline">
  
    <li><i class="fe fe-smile-alt"></i> <span id="busuanzi_value_site_uv"></span></li>
  
    <li><i class="fe fe-bookmark"></i> <span id="busuanzi_value_page_pv"></span></li>
  
</ul>
    </div>
    <ul class="list-inline">
      <li>&copy; 2020 OOOOONLY</li>
      <li>Powered by <a href="http://hexo.io/" target="_blank">Hexo</a></li>
      <li>Theme  <a href="https://github.com/zhwangart/hexo-theme-ocean" target="_blank" rel="noopener">Ocean</a></li>
    </ul>
  </div>
</footer>

</main>
<aside class="sidebar">
  <button class="navbar-toggle"></button>
<nav class="navbar">
  
    <div class="logo">
      <a href="/"><img src="/images/hexo.svg" alt="OOOOONLY"></a>
    </div>
  
  <ul class="nav nav-main">
    
      <li class="nav-item">
        <a class="nav-item-link" href="/">Home</a>
      </li>
    
      <li class="nav-item">
        <a class="nav-item-link" href="/archives">Archives</a>
      </li>
    
      <li class="nav-item">
        <a class="nav-item-link" href="/gallery">Gallery</a>
      </li>
    
      <li class="nav-item">
        <a class="nav-item-link" href="/about">About</a>
      </li>
    
    <li class="nav-item">
      <a class="nav-item-link nav-item-search" title="Search">
        <i class="fe fe-search"></i>
        Search
      </a>
    </li>
  </ul>
</nav>
<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      <div class="totop" id="totop">
  <i class="fe fe-rocket"></i>
</div>
    </li>
    <li class="nav-item">
      
        <a class="nav-item-link" target="_blank" href="/atom.xml" title="RSS Feed">
          <i class="fe fe-feed"></i>
        </a>
      
    </li>
  </ul>
</nav>
<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
</aside>

<script src="/js/jquery-2.0.3.min.js"></script>


<script src="/js/jquery.justifiedGallery.min.js"></script>


<script src="/js/lazyload.min.js"></script>


<script src="/js/busuanzi-2.3.pure.min.js"></script>


  
<script src="/fancybox/jquery.fancybox.min.js"></script>




  
<script src="/js/tocbot.min.js"></script>

  <script>
    // Tocbot_v4.7.0  http://tscanlin.github.io/tocbot/
    tocbot.init({
      tocSelector: '.tocbot',
      contentSelector: '.article-entry',
      headingSelector: 'h1, h2, h3, h4, h5, h6',
      hasInnerContainers: true,
      scrollSmooth: true,
      positionFixedSelector: '.tocbot',
      positionFixedClass: 'is-position-fixed',
      fixedSidebarOffset: 'auto',
    });
  </script>



<script src="/js/ocean.js"></script>


</body>
</html>